package com.example.csmallpassport.security;

import com.example.csmallpassport.mapper.AdminMapper;
import com.example.csmallpassport.pojo.vo.AdminLoginInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Service
@Slf4j
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    AdminMapper adminMapper;

    /**
     * 根据用户名加载用户详情
     * @param s login界面中user框位置输入的信息
     * @return 返回一个由我们设置的用户详情对象
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        log.debug("Spring secuity执行loadUserByUsername()构建UserDetails对象");

        AdminLoginInfoVO loginInfo = adminMapper.getLoginInfoByUsername(s);
        log.debug("根据【{}】用户名长查询到的信息为:  {}",s,loginInfo);
        if (loginInfo == null) {
            String message = "用户不存在，返回的UserDetails为null";
            log.warn(message);
            //InternalAuthenticationServiceException当loadUserByUsername方法返回值为null时会抛出此错误信息
            return null;
        }

/*        if(!"root".equals(s)){
            log.debug("用户名【{}】错误，将不会返回UserDetails(用户详情对象)",s);
            return null;
        }*/
/*        UserDetails userDetails = User.builder() //构建者模式
                .username(loginInfo.getUsername()) //存入用户名
                .password(loginInfo.getPassword()) //账号对应的密码，整张此处应该是加密状态的密码
                .disabled(loginInfo.getEnable() == 0) //存入账号的启用，禁用状态
                .accountLocked(false) //存入账号是否是锁定状态
                .credentialsExpired(false) //存入的凭证是否过期
                .accountExpired(false) //存入的账号是否过期
                .authorities("这是一个临时的权限信息") //设置此用户的权限信息
                .build(); //执行构建，得到UserDetails类型的对象*/

        Collection<GrantedAuthority> authorities = new ArrayList<>();
        List<String> permissions = loginInfo.getPermissions();
        for (String permission : permissions) {
            authorities.add(new SimpleGrantedAuthority(permission));
        }
        //AdminDetails继承了User类型，再User类型上进行了扩展，所以此处可以作为返回值类型来使用
        AdminDetails adminDetails = new AdminDetails(
                loginInfo.getId(),
                loginInfo.getUsername(),
                loginInfo.getPassword(),
                loginInfo.getEnable() == 1,
                authorities
        );
        log.debug("向Spring Security返回UserDetails类型的对象，返回结果:{}",adminDetails);
        return adminDetails;
    }
}
